package com.spark.lola.controller.logistics;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.spark.lola.logistics.entity.ExpensesCategory;
import com.spark.lola.logistics.entity.ExpensesInfo;
import com.spark.lola.logistics.request.ExpensesInfoAddRequest;
import com.spark.lola.logistics.request.ExpensesInfoUpdateRequest;
import com.spark.lola.logistics.service.ExpensesInfoService;
import com.spark.lola.logistics.vo.ExpensesAnalyzeVo;
import com.spark.lola.logistics.vo.ExpensesDetailVo;
import com.spark.lola.statistics.entity.StatisticsPurchase;
import com.spark.lola.support.common.constant.CommonConstant;
import com.spark.lola.support.common.entity.ShiroUser;
import com.spark.lola.support.common.util.ResponseBean;
import com.spark.lola.support.core.param.ExcelParams;
import com.spark.lola.support.mvc.service.ExcelServiceImpl;
import com.spark.lola.support.mybatis.common.QueryCondition;
import com.spark.lola.support.mybatis.controller.BaseController;
import com.spark.lola.support.mybatis.entity.PageParam;
import com.spark.lola.support.mybatis.entity.QueryParam;
import com.spark.lola.support.wms.configuration.WmsProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: Zhi-peng wang
 * @date: 2020/05/08 11:24
 * 货运支出单接口
 **/
@RestController
@RequestMapping("/api/logistics/expenses-info")
@Api(value = "/api/logistics/expenses-info", tags = "货运支出单接口")
public class ExpensesInfoController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ExpensesInfoController.class);

    @Autowired
    private ExpensesInfoService expensesInfoService;

    @Autowired
    private MyExcelServiceImpl excelService;


    @Autowired
    private WmsProperties wmsProperties;

    @ApiOperation(value = "分页查询货运支出单信息")
    @RequiresPermissions(value = "m5160")
    @RequestMapping(value = "/findBy", method = RequestMethod.POST)
    public ResponseBean findPage(@RequestBody QueryParam<ExpensesInfo> queryParam, @SessionAttribute ShiroUser shiroUser) {
        // 当前管理员是否货运业务岗位
        if (wmsProperties.getLogistics().getDutyId().get(1).equals(shiroUser.getDutyId())) {
            QueryCondition queryCondition = new QueryCondition();
            queryCondition.setKey("o.empId");
            queryCondition.setOper("=");
            queryCondition.setValue(shiroUser.getId());
            queryParam.getQueryList().add(queryCondition);
        }
        // 当前管理员是否隶属货运部 并管理指定用户
        if (!StringUtils.isEmpty(shiroUser.getControlUsers()) && wmsProperties.getLogistics().getDeptId().equals(shiroUser.getDeptId())) {
            // 绑定指定用户链
            bindControlQuery(queryParam, shiroUser, "o.empId", false);
        }
        IPage<ExpensesInfo> expensesInfoIPage = expensesInfoService.findPage(queryParam);
        return ResponseBean.success(expensesInfoIPage);
    }

    @ApiOperation(value = "获取货运支出单信息详情")
    @ApiImplicitParam(name = "id", value = "货运支出单信息id", required = true, dataType = "long", paramType = "path")
    @RequiresPermissions(value = "m5164")
    @RequestMapping(value = "/findInfo/{id}", method = RequestMethod.GET)
    public ResponseBean findInfo(@PathVariable long id, @SessionAttribute ShiroUser shiroUser) {
        ExpensesInfo expensesInfo = new ExpensesInfo();
        if (id != 0) {
            expensesInfo = expensesInfoService.findInfo(id);
        }
        return ResponseBean.success(expensesInfo);
    }

    @ApiOperation(value = "创建货运支出单")
    @RequiresPermissions(value = {"m5161", "m5163"}, logical = Logical.OR)
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean addExpenses(@RequestBody ExpensesInfo expensesInfo, @SessionAttribute ShiroUser shiroUser) throws Exception {
        ExpensesInfo model = new ExpensesInfo();
        BeanUtils.copyProperties(expensesInfo, model);
        if (expensesInfo.getId() == null) {
            model = expensesInfoService.addExpenses(model, shiroUser);
        } else {
            model = expensesInfoService.updateExpenses(model, shiroUser);
            return ResponseBean.success(model);
        }
        return ResponseBean.success(model);
    }

//    @ApiOperation(value = "修改货运支出单")
//    @RequiresPermissions(value = "", logical = Logical.OR)
//    @RequestMapping(value = "/update", method = RequestMethod.POST)
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseBean updateExpenses(@RequestBody ExpensesInfoUpdateRequest expensesInfoUpdateRequest, @SessionAttribute ShiroUser shiroUser) throws Exception {
//        ExpensesInfo model = new ExpensesInfo();
//        BeanUtils.copyProperties(expensesInfoUpdateRequest, model);
//        model = expensesInfoService.updateExpenses(model, shiroUser);
//        return ResponseBean.success(model);
//    }

    @ApiOperation(value = "删除货运支出单信息")
    @ApiImplicitParam(name = "nos", value = "删除货运支出单信息id集合", required = true, dataType = "Long", paramType = "query")
    @RequiresPermissions(value = "m5162")
    @RequestMapping(value = "/del", method = RequestMethod.GET)
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean del(@RequestParam(value = "nos") List<Long> ids, @SessionAttribute ShiroUser shiroUser) throws Exception {
        if (CollectionUtils.isEmpty(ids)) {
            return ResponseBean.error("id字符串集不能为空");
        }
        if (ids.size() > 1) {
            return ResponseBean.error("禁止批量操作");
        }
        expensesInfoService.deleteOrder(ids.get(0), shiroUser);
        return ResponseBean.success();
    }

    //    @ApiOperation(value = "货运支出单提交")
//    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
//    @RequiresPermissions(value = "m5165")
//    @RequestMapping(value = "/submit", method = RequestMethod.POST)
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseBean submit(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
//        Long expensesId = jsonObject.getLong("expensesId");
//        if (expensesId == null) {
//            return ResponseBean.error("参数为空");
//        }
//        expensesInfoService.audit(expensesId, shiroUser);
//        return ResponseBean.success();
//    }
//
//    @ApiOperation(value = "货运支出单物流主管审核")
//    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
//    @RequiresPermissions(value = "m51691")
//    @RequestMapping(value = "/logisticsAudit", method = RequestMethod.POST)
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseBean logisticsAudit(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
//        Long expensesId = jsonObject.getLong("expensesId");
//        String msg = jsonObject.getString("msg");
//        if (expensesId == null) {
//            return ResponseBean.error("参数为空");
//        }
//        expensesInfoService.logisticsAudit(expensesId, msg, shiroUser);
//        return ResponseBean.success();
//    }
//
    @ApiOperation(value = "货运支出单财务结算")
    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
    @RequiresPermissions(value = "m5165")
    @RequestMapping(value = "/financeAudit", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean financeAudit(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
        Long expensesId = jsonObject.getLong("expensesId");
        BigDecimal refundableFee = jsonObject.getBigDecimal("refundableFee");
        String msg = jsonObject.getString("msg");
        if (expensesId == null) {
            return ResponseBean.error("参数为空");
        }
        expensesInfoService.financeAudit(expensesId, refundableFee, msg, shiroUser);
        return ResponseBean.success();
    }

//    @ApiOperation(value = "货运支出单取消")
//    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
//    @RequiresPermissions(value = "m5167")
//    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
//    @Transactional(rollbackFor = Exception.class)
//    public ResponseBean cancel(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
//        Long expensesId = jsonObject.getLong("expensesId");
//        String msg = jsonObject.getString("msg");
//        if (expensesId == null || msg == null) {
//            return ResponseBean.error("参数为空");
//        }
//        expensesInfoService.cancel(expensesId, msg, shiroUser);
//        return ResponseBean.success();
//    }

    @ApiOperation(value = "货运支出单确认")
    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
    @RequiresPermissions(value = "m5168")
    @RequestMapping(value = "/complete", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean complete(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
        Long expensesId = jsonObject.getLong("expensesId");
        String evidence = jsonObject.getString("evidence");
        if (expensesId == null) {
            return ResponseBean.error("参数为空");
        }
        expensesInfoService.complete(expensesId, evidence, shiroUser);
        return ResponseBean.success();
    }

    @ApiOperation(value = "货运支出单驳回")
    @ApiImplicitParam(name = "expensesId", value = "货运支出单信息id", required = true, dataType = "long", paramType = "query")
    @RequiresPermissions(value = "m5166")
    @RequestMapping(value = "/rejected", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean rejected(@RequestBody JSONObject jsonObject, @SessionAttribute ShiroUser shiroUser) throws Exception {
        Long expensesId = jsonObject.getLong("expensesId");
        String msg = jsonObject.getString("msg");
        if (expensesId == null || msg == null) {
            return ResponseBean.error("参数为空");
        }
        expensesInfoService.rejected(expensesId, msg, shiroUser);
        return ResponseBean.success();
    }

    @ApiOperation(value = "物流分析")
    @RequiresPermissions(value = "m5190")
    @RequestMapping(value = "/analyze/findBy", method = RequestMethod.POST)
    public ResponseBean findPageAnalyze(@RequestBody QueryParam<ExpensesAnalyzeVo> queryParam, @SessionAttribute ShiroUser shiroUser) {
//        // 当前管理员是否货运业务岗位
//        if (wmsProperties.getLogistics().getDutyId().get(1).equals(shiroUser.getDutyId())) {
//            QueryCondition queryCondition = new QueryCondition();
//            queryCondition.setKey("o.empId");
//            queryCondition.setOper("=");
//            queryCondition.setValue(shiroUser.getId());
//            queryParam.getQueryList().add(queryCondition);
//        }
        IPage<ExpensesAnalyzeVo> page = expensesInfoService.findPageAnalyze(queryParam);
        return ResponseBean.success(page);
    }

    @RequiresPermissions(value = "m5190")
    @RequestMapping(value = "/analyze/excel-out", method = RequestMethod.POST)
    public ResponseBean excelOut(@RequestBody ExcelParams<ExpensesAnalyzeVo, QueryParam<ExpensesAnalyzeVo>> excelParams, @SessionAttribute ShiroUser shiroUser) {
        logger.info("===管理员【{}】导出物流分析报表Excel===START===", shiroUser.getLoginNo());
        IPage<ExpensesAnalyzeVo> page = expensesInfoService.findPageAnalyze(excelParams.getQueryParam());
        logger.info("===数据量【{}】待生成", page.getTotal());
        ResponseBean responseBean = excelService.create(excelParams.getFileds(), page.getRecords(), StatisticsPurchase.class);
        logger.info("===管理员【{}】导出物流分析报表Excel===END===", shiroUser.getLoginNo());
        return responseBean;
    }

}
